//
//  YHPDFImageDraw.m
//  YHPDFImageLoader
//
//  Created by yaheng on 16/10/10.
//  Copyright © 2016年 yaheng. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "YHPDFImageDraw.h"

@implementation YHPDFImageDraw

+ (UIImage *)drawImageWithURL:(NSURL *)url size:(CGSize)size canStretched:(BOOL)stretched {
    return [YHPDFImageDraw drawImageWithURL:url size:size canStretched:stretched page:1];
}

+ (UIImage *)drawImageWithURL:(NSURL *)url size:(CGSize)size canStretched:(BOOL)stretched page:(NSUInteger)page {
    CGFloat screenScale = [UIScreen mainScreen].scale;
//    screenScale = 1.2;
    CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithURL((__bridge CFURLRef)url);
    
    CGPDFPageRef imagePage = CGPDFDocumentGetPage(pdfRef, page);
    CGRect pdfRect = CGPDFPageGetBoxRect(imagePage, kCGPDFCropBox);
    
    CGSize contextSize;
    if (size.width <= 0 || size.height <= 0) {
        contextSize = pdfRect.size;
    }else {
        contextSize = size;
    }
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    /* 参数说明
     * data : 如果不为 NULL 那么它应该指向一块大小至少为bytesPerRow * height 字节的内存；如果 为 NULL ，那么系统就会为我们自动分配和释放所需的内存，所以一般指定 NULL 即可；
     * width 和 height ：位图的宽度和高度，分别赋值为图片的 像素宽度 和 像素高度即可；
     * bitsPerComponent ：像素的每个颜色分量使用的 bit 数，在 RGB 颜色空间下指定 8 即可；
     * bytesPerRow ：位图的每一行使用的字节数，大小至少为 width * bytes per pixel 字节。有意思的是，当我们指定 0 时，系统不仅会为我们自动计算，而且还会进行 cache line alignment 的优化
     * space : 颜色空间,RGB即可
     * bitmapInfo : 位图布局信息
     [self YHByteAlignForCoreAnimationBytesPerRow:((size_t)contextSize.width) * 8]
     */
    CGContextRef context = CGBitmapContextCreate(NULL,
                                                 contextSize.width * screenScale,
                                                 contextSize.height * screenScale,
                                                 8,
                                                 [self YHByteAlignForCoreAnimationBytesPerRow:((size_t)contextSize.width * screenScale) * 4],
                                                 colorSpace,
                                                 kCGImageAlphaPremultipliedLast);
    CGContextScaleCTM(context, screenScale, screenScale);
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);
    if (size.width > 0 && size.height > 0) {
        CGFloat widthScale = size.width / pdfRect.size.width;
        CGFloat heightScale = size.height / pdfRect.size.height;
        
        if (!stretched) {
            heightScale = widthScale < heightScale ? widthScale : heightScale;
            widthScale = heightScale < widthScale ? heightScale : widthScale;
        }
    
        CGContextScaleCTM(context, widthScale, heightScale);
        CGContextTranslateCTM(context, -pdfRect.origin.x, -pdfRect.origin.y);
    }else {
        CGAffineTransform drawingTransform = CGPDFPageGetDrawingTransform(imagePage, kCGPDFCropBox, pdfRect, 0, true);
        CGContextConcatCTM(context, drawingTransform);
    }
    
    CGContextDrawPDFPage(context, imagePage);
    CGPDFDocumentRelease(pdfRef);
    
    CGImageRef image = CGBitmapContextCreateImage(context);
    UIImage *pdfImage = [[UIImage alloc] initWithCGImage:image scale:screenScale orientation:UIImageOrientationUp];
    
    CGImageRelease(image);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    
    return pdfImage;
}

+ (size_t)YHByteAlignForCoreAnimationBytesPerRow:(size_t)bytesPerRow {
    return [self YHByteAlignForWidth:bytesPerRow alignment: 64];
}

+ (size_t)YHByteAlignForWidth:(size_t)width alignment:(size_t)alignment {
    // 返回数据需要开辟多大内存对齐的数据块大小
    return ((width + (alignment - 1)) / alignment) * alignment;
}
@end
